// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2008-2015 Freescale Semiconductor Inc.
 */

#define FM_DMP_PGSZ_ERR { \
			snprintf(&buf[PAGE_SIZE - 80], 70, \
			"\n Err: current sysfs buffer reached PAGE_SIZE\n");\
			n = PAGE_SIZE - 2; \
			}

#define FM_DMP_LN(buf, n, ...) \
	do { \
		int k, m = n; \
		m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
		if (k < 0 || m > PAGE_SIZE - 90) \
			FM_DMP_PGSZ_ERR \
		n = m; \
	} while (0)

#define FM_DMP_TITLE(buf, n, addr, ...) \
	do { \
		int k, m = n; \
		m += k = snprintf(&buf[m], PAGE_SIZE - m, "\n"); \
		if (k < 0 || m > PAGE_SIZE - 90) \
			FM_DMP_PGSZ_ERR \
		m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
		if (k < 0 || m > PAGE_SIZE - 90) \
			FM_DMP_PGSZ_ERR \
		if (addr) {                           \
			phys_addr_t pa; \
			pa = virt_to_phys(addr); \
			m += k = \
			snprintf(&buf[m], PAGE_SIZE - m, " (0x%lX)", \
				(unsigned long)(pa)); \
			if (k < 0 || m > PAGE_SIZE - 90) \
				FM_DMP_PGSZ_ERR \
		} \
		m += k = snprintf(&buf[m], PAGE_SIZE - m, \
			"\n----------------------------------------\n\n"); \
			if (k < 0 || m > PAGE_SIZE - 90) \
				FM_DMP_PGSZ_ERR \
		n = m; \
	} while (0)

#define FM_DMP_SUBTITLE(buf, n, ...) \
	do { \
		int k, m = n; \
		m += k = snprintf(&buf[m], PAGE_SIZE - m, "------- "); \
		if (k < 0 || m > PAGE_SIZE - 90) \
			FM_DMP_PGSZ_ERR \
		m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
		if (k < 0 || m > PAGE_SIZE - 90) \
			FM_DMP_PGSZ_ERR \
		m += k = snprintf(&buf[m], PAGE_SIZE - m, "\n"); \
		if (k < 0 || m > PAGE_SIZE - 90) \
			FM_DMP_PGSZ_ERR \
		n = m; \
	} while (0)

#define FM_DMP_V32(buf, n, st, phrase) \
	do { \
		int k, m = n; \
		phys_addr_t pa = virt_to_phys(&((st)->phrase)); \
		k = snprintf(&buf[m], PAGE_SIZE - m, \
		"0x%010llX: 0x%08x%8s\t%s\n", (unsigned long long) pa, \
		ioread32be((uint32_t *)&((st)->phrase)), "", #phrase); \
		if (k < 0 || m > PAGE_SIZE - 90) \
			FM_DMP_PGSZ_ERR \
		n += k; \
	} while (0)

int memac_dump_regs(struct fman_mac *memac, char *buf, int nn)
{
	struct memac_regs __iomem *p_mm = (struct memac_regs *)memac->regs;
	int			i = 0, n = nn;

	FM_DMP_SUBTITLE(buf, n, "\n");
	FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d", memac->mac_id);

	FM_DMP_V32(buf, n, p_mm, command_config);
	FM_DMP_V32(buf, n, p_mm, mac_addr0.mac_addr_l);
	FM_DMP_V32(buf, n, p_mm, mac_addr0.mac_addr_u);
	FM_DMP_V32(buf, n, p_mm, maxfrm);
	FM_DMP_V32(buf, n, p_mm, hashtable_ctrl);
	FM_DMP_V32(buf, n, p_mm, ievent);
	FM_DMP_V32(buf, n, p_mm, tx_ipg_length);
	FM_DMP_V32(buf, n, p_mm, imask);

	for (i = 0; i < 4; ++i)
		FM_DMP_V32(buf, n, p_mm, pause_quanta[i]);

	for (i = 0; i < 4; ++i)
		FM_DMP_V32(buf, n, p_mm, pause_thresh[i]);

	FM_DMP_V32(buf, n, p_mm, rx_pause_status);

	for (i = 0; i < MEMAC_NUM_OF_PADDRS; ++i) {
		FM_DMP_V32(buf, n, p_mm, mac_addr[i].mac_addr_l);
		FM_DMP_V32(buf, n, p_mm, mac_addr[i].mac_addr_u);
	}

	FM_DMP_V32(buf, n, p_mm, lpwake_timer);
	FM_DMP_V32(buf, n, p_mm, sleep_timer);
	FM_DMP_V32(buf, n, p_mm, statn_config);
	FM_DMP_V32(buf, n, p_mm, if_mode);
	FM_DMP_V32(buf, n, p_mm, if_status);
	FM_DMP_V32(buf, n, p_mm, hg_config);
	FM_DMP_V32(buf, n, p_mm, hg_pause_quanta);
	FM_DMP_V32(buf, n, p_mm, hg_pause_thresh);
	FM_DMP_V32(buf, n, p_mm, hgrx_pause_status);
	FM_DMP_V32(buf, n, p_mm, hg_fifos_status);
	FM_DMP_V32(buf, n, p_mm, rhm);
	FM_DMP_V32(buf, n, p_mm, thm);

	return n;
}

int memac_dump_regs_rx(struct fman_mac *memac, char *buf, int nn)
{
	struct memac_regs __iomem *p_mm = (struct memac_regs *)memac->regs;
	int n = nn;

	FM_DMP_SUBTITLE(buf, n, "\n");
	FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d Rx stats", memac->mac_id);

	/* Rx Statistics Counter */
	FM_DMP_V32(buf, n, p_mm, reoct_l);
	FM_DMP_V32(buf, n, p_mm, reoct_u);
	FM_DMP_V32(buf, n, p_mm, roct_l);
	FM_DMP_V32(buf, n, p_mm, roct_u);
	FM_DMP_V32(buf, n, p_mm, raln_l);
	FM_DMP_V32(buf, n, p_mm, raln_u);
	FM_DMP_V32(buf, n, p_mm, rxpf_l);
	FM_DMP_V32(buf, n, p_mm, rxpf_u);
	FM_DMP_V32(buf, n, p_mm, rfrm_l);
	FM_DMP_V32(buf, n, p_mm, rfrm_u);
	FM_DMP_V32(buf, n, p_mm, rfcs_l);
	FM_DMP_V32(buf, n, p_mm, rfcs_u);
	FM_DMP_V32(buf, n, p_mm, rvlan_l);
	FM_DMP_V32(buf, n, p_mm, rvlan_u);
	FM_DMP_V32(buf, n, p_mm, rerr_l);
	FM_DMP_V32(buf, n, p_mm, rerr_u);
	FM_DMP_V32(buf, n, p_mm, ruca_l);
	FM_DMP_V32(buf, n, p_mm, ruca_u);
	FM_DMP_V32(buf, n, p_mm, rmca_l);
	FM_DMP_V32(buf, n, p_mm, rmca_u);
	FM_DMP_V32(buf, n, p_mm, rbca_l);
	FM_DMP_V32(buf, n, p_mm, rbca_u);
	FM_DMP_V32(buf, n, p_mm, rdrp_l);
	FM_DMP_V32(buf, n, p_mm, rdrp_u);
	FM_DMP_V32(buf, n, p_mm, rpkt_l);
	FM_DMP_V32(buf, n, p_mm, rpkt_u);
	FM_DMP_V32(buf, n, p_mm, rund_l);
	FM_DMP_V32(buf, n, p_mm, rund_u);
	FM_DMP_V32(buf, n, p_mm, r64_l);
	FM_DMP_V32(buf, n, p_mm, r64_u);
	FM_DMP_V32(buf, n, p_mm, r127_l);
	FM_DMP_V32(buf, n, p_mm, r127_u);
	FM_DMP_V32(buf, n, p_mm, r255_l);
	FM_DMP_V32(buf, n, p_mm, r255_u);
	FM_DMP_V32(buf, n, p_mm, r511_l);
	FM_DMP_V32(buf, n, p_mm, r511_u);
	FM_DMP_V32(buf, n, p_mm, r1023_l);
	FM_DMP_V32(buf, n, p_mm, r1023_u);
	FM_DMP_V32(buf, n, p_mm, r1518_l);
	FM_DMP_V32(buf, n, p_mm, r1518_u);
	FM_DMP_V32(buf, n, p_mm, r1519x_l);
	FM_DMP_V32(buf, n, p_mm, r1519x_u);
	FM_DMP_V32(buf, n, p_mm, rovr_l);
	FM_DMP_V32(buf, n, p_mm, rovr_u);
	FM_DMP_V32(buf, n, p_mm, rjbr_l);
	FM_DMP_V32(buf, n, p_mm, rjbr_u);
	FM_DMP_V32(buf, n, p_mm, rfrg_l);
	FM_DMP_V32(buf, n, p_mm, rfrg_u);
	FM_DMP_V32(buf, n, p_mm, rcnp_l);
	FM_DMP_V32(buf, n, p_mm, rcnp_u);
	FM_DMP_V32(buf, n, p_mm, rdrntp_l);
	FM_DMP_V32(buf, n, p_mm, rdrntp_u);

	return n;
}

int memac_dump_regs_tx(struct fman_mac *memac, char *buf, int nn)
{
	struct memac_regs __iomem *p_mm = (struct memac_regs *)memac->regs;
	int n = nn;

	FM_DMP_SUBTITLE(buf, n, "\n");
	FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d Tx stats", memac->mac_id);

	/* Tx Statistics Counter */
	FM_DMP_V32(buf, n, p_mm, teoct_l);
	FM_DMP_V32(buf, n, p_mm, teoct_u);
	FM_DMP_V32(buf, n, p_mm, toct_l);
	FM_DMP_V32(buf, n, p_mm, toct_u);
	FM_DMP_V32(buf, n, p_mm, txpf_l);
	FM_DMP_V32(buf, n, p_mm, txpf_u);
	FM_DMP_V32(buf, n, p_mm, tfrm_l);
	FM_DMP_V32(buf, n, p_mm, tfrm_u);
	FM_DMP_V32(buf, n, p_mm, tfcs_l);
	FM_DMP_V32(buf, n, p_mm, tfcs_u);
	FM_DMP_V32(buf, n, p_mm, tvlan_l);
	FM_DMP_V32(buf, n, p_mm, tvlan_u);
	FM_DMP_V32(buf, n, p_mm, terr_l);
	FM_DMP_V32(buf, n, p_mm, terr_u);
	FM_DMP_V32(buf, n, p_mm, tuca_l);
	FM_DMP_V32(buf, n, p_mm, tuca_u);
	FM_DMP_V32(buf, n, p_mm, tmca_l);
	FM_DMP_V32(buf, n, p_mm, tmca_u);
	FM_DMP_V32(buf, n, p_mm, tbca_l);
	FM_DMP_V32(buf, n, p_mm, tbca_u);
	FM_DMP_V32(buf, n, p_mm, tpkt_l);
	FM_DMP_V32(buf, n, p_mm, tpkt_u);
	FM_DMP_V32(buf, n, p_mm, tund_l);
	FM_DMP_V32(buf, n, p_mm, tund_u);
	FM_DMP_V32(buf, n, p_mm, t64_l);
	FM_DMP_V32(buf, n, p_mm, t64_u);
	FM_DMP_V32(buf, n, p_mm, t127_l);
	FM_DMP_V32(buf, n, p_mm, t127_u);
	FM_DMP_V32(buf, n, p_mm, t255_l);
	FM_DMP_V32(buf, n, p_mm, t255_u);
	FM_DMP_V32(buf, n, p_mm, t511_l);
	FM_DMP_V32(buf, n, p_mm, t511_u);
	FM_DMP_V32(buf, n, p_mm, t1023_l);
	FM_DMP_V32(buf, n, p_mm, t1023_u);
	FM_DMP_V32(buf, n, p_mm, t1518_l);
	FM_DMP_V32(buf, n, p_mm, t1518_u);
	FM_DMP_V32(buf, n, p_mm, t1519x_l);
	FM_DMP_V32(buf, n, p_mm, t1519x_u);
	FM_DMP_V32(buf, n, p_mm, tcnp_l);
	FM_DMP_V32(buf, n, p_mm, tcnp_u);

	return n;
}

bool fsl_memac_can_read_reg(struct fman_mac *memac)
{
	struct memac_regs *mregs = memac->regs;

	if (mregs != NULL)
		return true;
	else
		return false;
}

u32 fsl_memac_read_reg(struct fman_mac *memac, unsigned int regoff)
{
	struct memac_regs *mregs = memac->regs;
	void *tmp_reg_addr = NULL;

	tmp_reg_addr = ((void *)mregs + regoff);
	return ioread32be(tmp_reg_addr);
}

